#ifndef __PANEL_PRESET_H__
#define __PANEL_PRESET_H__

#include <wx/wx.h>
#include <wx/aui/aui.h>
#include <wx/wrapsizer.h>

#define preset_max  6

#define EFFECT_INDEX_REVERB         0
#define EFFECT_INDEX_CHORUS         1
#define EFFECT_INDEX_DELAY          2
#define EFFECT_INDEX_WAH            3
#define EFFECT_INDEX_DISTORTION1    4
#define EFFECT_INDEX_DISTORTION2    5
#define EFFECT_INDEX_NONE           255


class MyEventPreset : public wxCommandEvent {
public:
    MyEventPreset(wxEventType eventType = wxEVT_NULL,int id = 0)
        : wxCommandEvent(eventType, id) {

        }

    // 克隆事件对象
//    [[nodiscard]] // C++17 才支持，意思就是函数返回值不能被忽略，否则编译器发出警告
    virtual wxEvent *Clone() const override {
        return new MyEventPreset(*this);
    }

    void SetPresetIndex(const unsigned int index) {
        preset_index = index;
    }
    int GetPresetIndex() {
        return preset_index;
    }
    void SetEffectStatusReverb(const bool status) {
        effect_status_reverb = status;
    }
    void SetEffectStatusChorus(const bool status) {
        effect_status_chorus = status;
    }
    void SetEffectStatusDelay(const bool status) {
        effect_status_delay = status;
    }
    void SetEffectStatusWah(const bool status) {
        effect_status_wah = status;
    }
    void SetEffectStatusDistortion1(const bool status) {
        effect_status_distortion1 = status;
    }
    void SetEffectStatusDistortion2(const bool status) {
        effect_status_distortion2 = status;
    }

    bool GetEffectStatusReverb() {
        return effect_status_reverb;
    }
    bool GetEffectStatusChorus() {
        return effect_status_chorus;
    }
    bool GetEffectStatusDelay() {
        return effect_status_delay;
    }
    bool GetEffectStatusWah() {
        return effect_status_wah;
    }
    bool GetEffectStatusDistortion1() {
        return effect_status_distortion1;
    }
    bool GetEffectStatusDistortion2() {
        return effect_status_distortion2;
    }

private:

    int preset_index;
    bool effect_status_reverb;
    bool effect_status_chorus;
    bool effect_status_delay;
    bool effect_status_wah;
    bool effect_status_distortion1;
    bool effect_status_distortion2;

};

wxDECLARE_EVENT(myEVT_PRESET, MyEventPreset);
wxDECLARE_EVENT(myEVT_PRESET_INDEX, MyEventPreset);
wxDECLARE_EVENT(myEVT_PRESET_EFFECT_STATUS_UPDATE, MyEventPreset);

typedef void (wxEvtHandler::*MyPresetEventFunction)(MyEventPreset &);

#define MyPresetEventHandler(func) \
    wxEVENT_HANDLER_CAST(MyPresetEventFunction, func)

#define M_EVT_PRESET(id, fn) \
    wx__DECLARE_EVT1(myEVT_PRESET, id, MyPresetEventHandler(fn))
#define M_EVT_PRESET_INDEX(id, fn) \
    wx__DECLARE_EVT1(myEVT_PRESET_INDEX, id, MyPresetEventHandler(fn))
#define M_EVT_PRESET_EFFECT_STATUS_UPDATE(id, fn) \
    wx__DECLARE_EVT1(myEVT_PRESET_EFFECT_STATUS_UPDATE, id, MyPresetEventHandler(fn))


class PanelPreset : public wxPanel
{
public:
    typedef struct
    {
        int preset_index;
        uint32_t effect_status_mark;
    }param_struct;
    PanelPreset(const wxString &title, wxWindowID id = wxID_ANY, wxWindow *parent = nullptr);

private:
    wxAuiPaneInfo paneInfo;
    // wxBoxSizer *layout;
    wxWindowID ID_BTN_PRESET[preset_max];
    wxWindowID ID_CHK_DST1[preset_max];
    wxWindowID ID_CHK_DST2[preset_max];
    wxWindowID ID_CHK_REV[preset_max];
    wxWindowID ID_CHK_CHR[preset_max];
    wxWindowID ID_CHK_DLY[preset_max];
    wxWindowID ID_CHK_WAH[preset_max];
    int current_preset;
    int effect_status_reverb[preset_max];
    int effect_status_chorus[preset_max];
    int effect_status_delay[preset_max];
    int effect_status_wah[preset_max];
    int effect_status_distortion1[preset_max];
    int effect_status_distortion2[preset_max];
    MyEventPreset param_event;

public:

    wxAuiPaneInfo &GetPaneInfo();
    void SetShow(bool show);
    void SetPreset(int preset);
    int GetPreset();
    void PresetEffectStatusInit(int preset,int effect,int status);

private:

    void OnBtnPreset(wxCommandEvent& event);
    void OnChkChange(wxCommandEvent& event);
    void OnBtnMouseEnter(wxMouseEvent& event);

};


#endif
